#include "configdata.h"
#include "stdio.h"
#include <fstream>
#include "aisinoutils.h"

const std::string ConfigData::AISINO_CONFIG_FILE_NAME = "aisino.cfg";

const std::string ConfigData::CONFIG_KEYS[] = {
                                                AISINO_CONFIG_FILE,
                                                AISINO_SINGLE_DATABASE_FILE,
                                                AISINO_MULTIPLE_DATABASE_FILE,
                                                AISINO_EXAM_FILE,
                                                AISINO_QUESTION_NUM_PREFIX,
                                                AISINO_QUESTION_NUM_SUFFIX,
                                                AISINO_QUESTION_TEXT_PREFIX,
                                                AISINO_QUESTION_TEXT_SUFFIX,
                                                AISINO_ANSWER_TEXT_PREFIX,
                                                AISINO_ANSWER_TEXT_SUFFIX,
                                                AISINO_OUTPUT_FILE_NAME,
                                                AISINO_OUTPUT_FILE_FLAG,
                                                AISINO_EMPTY_STRING};

ConfigData::ConfigData()
{
    this->config.clear();
    this->initConfigKeys();
}

ConfigData::~ConfigData()
{
    this->config.clear();
}

bool ConfigData::loadConfigFile(const std::string fileName)
{
    std::fstream file(fileName,std::ios_base::in);

    if(!file.is_open())
    {
        printf("can't open file: '%s'\n",fileName.c_str());
        return false;
    }

    this->setConfigValue(AISINO_CONFIG_FILE,AISINO_CONFIG_FILE_NAME);

    std::string text;
    unsigned int line = 0;

    while(std::getline(file,text))
    {
        line ++;
        std::string tag  = AISINO_CONFIG_KEY_AND_VALUE_TAG;
        if(!AisinoUtils::isStringWithTag(text,tag))
        {
            printf("line:%d not have the tag:'%s'\n",line,AISINO_CONFIG_KEY_AND_VALUE_TAG.c_str());
            continue;
        }
        std::string key = AisinoUtils::getStringFrontTag(text,tag);
        std::string value = AisinoUtils::getStringBehindTag(text,tag);
        this->setConfigValue(key,value);
    }

    file.close();

    bool ConfigDataOk = true;
    for(unsigned int i = 0 ; CONFIG_KEYS[i] != AISINO_EMPTY_STRING; i++)
    {
        if(0 == this->getConfigValue(CONFIG_KEYS[i]).compare(AISINO_EMPTY_STRING))
        {
            printf("'%s' not init\n",CONFIG_KEYS[i].c_str());
            ConfigDataOk = false;
        }
    }

    return ConfigDataOk;
}

void ConfigData::initConfigKeys()
{
   for(unsigned int i = 0 ; 0 != ConfigData::CONFIG_KEYS[i].compare(AISINO_EMPTY_STRING); i++ )
   {
        this->config[ConfigData::CONFIG_KEYS[i]] = AISINO_EMPTY_STRING;
   }
}

bool ConfigData::setConfigValue(const std::string key,std::string value)
{
    std::map<std::string,std::string>::iterator keyAndValue = config.find(key);
    if(keyAndValue == config.end())
    {
        printf("invalid key: %s\n",key.c_str());
        return false;
    }

    if(AISINO_EMPTY_STRING.compare(keyAndValue->second) != 0)
    {
        printf("failed,allready set value.key:%s\n",key.c_str());
        return false;
    }

    keyAndValue->second = value;
    return true;
}

const std::string& ConfigData::getConfigValue(const std::string key)
{
    std::map<std::string,std::string>::iterator keyAndValue = config.find(key);
    if(keyAndValue == config.end())
    {
        printf("not find key:%s\n",key.c_str());
        return AISINO_EMPTY_STRING;
    }

    return keyAndValue->second;
}
